<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <title>分页封装</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            user-select: none;
        }

        i {
            font-style: normal;
        }

        ul {
            list-style: none;
        }

        html,
        body {
            width: 100%;
            height: 100%;
            background-color: #f8f9ff;
        }

        .container {
            width: 100%;
            height: 100%;
        }

        .wrap {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            /* 弹性盒模型，如果居中没有高度就不会居中 */
        }

        .s-wrap-1 {
            display: flex;
            flex-direction: column;
            align-items: center;
            width: 600px;
        }

        .wrap .wrap-content {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
        }

        .wrap .wrap-content li {
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            width: 100px;
            height: 100px;
            align-items: center;
            padding: 10px;
        }

        .wrap .wrap-content li i {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 75px;
            height: 75px;
            font-size: 30px;
            border-radius: 8px;
            color: #646b8a;
            background-color: #fff;
            cursor: pointer;
            transition: all .3s;
            box-shadow: 0 16px 32px rgb(90 100 130 / 10%);
        }

        .wrap .wrap-content li i:hover {
            color: #6b5bfd;
            transform: scale(1.2);
        }

        .wrap .wrap-content li span {
            display: flex;
            font-size: 13px;
            color: #cdd5f7;
        }

        /* 这个是分页条 */
        .pagination {
            display: flex;
            height: 50px;
            align-items: center;
            margin: 30px;
            border-radius: 8px;
            background-color: #fff;
            box-shadow: 0 16px 32px rgb(90 100 130 / 10%);
        }

        .pagination li {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 25px;
            height: 25px;
            margin: 10px;
            font-size: 14px;
            border-radius: 5px;
            transition: all .3s;
        }

        .pagination li.page-btn {
            color: #cdd5f7;
            font-size: 22px;
        }

        .pagination li.page-btn.isClick {
            color: #646b8a;
            cursor: pointer;
        }

        .pagination li.page-btn.notClick {
            cursor: not-allowed;
        }

        .pagination li.page-btn.isClick:hover {
            color: #fff;
            background-color: #6b5bfd;
        }

        .pagination li.page-number {
            color: #646b8a;
            cursor: pointer;
        }

        .pagination li.page-number:hover {
            color: #fff;
            font-weight: bold;
            background-color: #6b5bfd;
        }

        .pagination li.page-number.active {
            color: #fff;
            font-weight: bold;
            background-color: #6b5bfd;
        }

        .pagination li.page-dot {
            color: #cdd5f7;
            font-size: 18px;
            cursor: pointer;
        }

        .pagination li.page-dot::after {
            content: "more_horiz";
        }

        .pagination li.page-dot:hover {
            color: #6b5bfd;
        }

        .pagination li.page-dot.page-dot-prev:hover::after {
            content: "first_page";
        }

        .pagination li.page-dot.page-dot-next:hover::after {
            content: "last_page";
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="wrap">
            <div class="s-wrap-1">
                <ul class="wrap-content"></ul>
                <div class="s-wrap-2">
                    <ul class="pagination">
                    </ul>
                </div>
            </div>
        </div>
    </div>
    <script>
        /*  icons为预先准备好的图标
            size为每页显示的个数
            page是显示的总页数 向上取整(一个也会占一页)
            buttonCount为要显示的数字按钮的个数 */
        const icons = [
            "pregnant_woman",
            "accessibility",
            "accessibility_new",
            "sports_kabaddi",
            "sports_handball",
            "elderly",
            "accessible",
            "accessible_forward",
            "hotel",
            "sports_baseball",
            "sports_basketball",
            "sports_football",
            "sports_golf",
            "sports_hockey",
            "sports_motorsports",
            "sports_rugby",
            "sports_soccer",
            "sports_tennis",
            "sports_volleyball",
            "pedal_bike",
            "moped",
            "two_wheeler",
            "directions_car",
            "local_taxi",
            "local_shipping",
            "directions_bus",
            "directions_transit",
            "subway",
            "flight",
            "mouse",
            "keyboard",
            "headset",
            "desktop_mac",
            "sim_card",
            "phone_android",
            "phone_iphone",
            "watch",
            "videogame_asset",
            "scanner",
            "attach_email",
            "attachment",
            "cloud_circle",
            "cloud_download",
            "cloud_upload",
            "text_snippet",
            "request_quote",
            "folder",
            "topic",
            "folder_shared",
            "4k",
            "fiber_new",
            "fiber_dvr",
            "explicit",
            "closed_caption",
            "hd",
            "high_quality",
            "closed_caption_disabled",
            "score",
            "picture_as_pdf",
            "filter_1",
            "filter_2",
            "filter_3",
            "filter_4",
            "filter_5",
            "filter_6",
            "filter_7",
            "filter_8",
            "filter_9",
            "filter_9_plus",
            "looks_one",
            "looks_two",
            "looks_3",
            "looks_4",
            "looks_5",
            "exposure_neg_1",
            "exposure_neg_2",
            "exposure_zero",
            "exposure_plus_1",
            "exposure_plus_2",
            "camera_alt",
            "center_focus_strong",
            "camera",
            "camera_roll",
            "photo",
            "movie_creation",
            "motion_photos_on",
            "motion_photos_paused",
            "local_movies",
            "movie_filter",
            "arrow_forward",
            "arrow_back",
            "subdirectory_arrow_right",
            "subdirectory_arrow_left",
            "arrow_downward",
            "arrow_upward",
            "north_east",
            "north_west",
            "south_east",
            "south_west",
            "error",
            "auto_delete"
        ],
            size = 10,
            page = Math.ceil(icons.length / size),
            buttonCount = 5;
        // 当前选中的页数
        let current = 1;

        /******************显示内容列表开始**************************/
        const _content = document.querySelector(".wrap-content");
        //定义显示内容的函数
        const showContent = () => {
            // 每次遍历新内容 首先清空  不然就会追加到里面去，造成页面混乱
            _content.innerHTML = "";
            icons.forEach((item, index) => {
                //遍历方法,筛选渲染的内容，0-10,10-20.
                if (index >= (current - 1) * size && index < current * size) {
                    //每遍历一遍创建一个li
                    const li = document.createElement('li');
                    li.innerHTML = `<i class="material-icons">${item}</i>
                        <span>${index + 1}</span>`;
                    //添加到对应的节点里面去
                    _content.appendChild(li);
                }
            })
        }
        /******************显示内容列表结束**************************/

        /******************创建分页列表开始**************************/
        //选择对应的节点 
        const _pagination = document.querySelector(".pagination");
        // 定义创建节点的函数
        const createPagination = () => {
            //调用显示内容函数
            showContent();
            //要显示左边的按钮
            let lis = `<li class="material-icons page-btn page-btn-prev ${current !== 1 ? "isClick" : 'notClick'}">
                            keyboard_arrow_left
                        </li>`;
            //做容错
            if (current < 1 || current > page) {
                alert(`参数最小值为1,最大值为${page}`)
            } else if (buttonCount < 5) {
                alert(`buttonCount参数最小值为5,低于5是没有意义的`);
            } else if (page <= buttonCount) {
                //如果总页数小于要显示的按钮的个数，就直接遍历，不显示省略符号
                for (let i = 1; i <= page; i++) {
                    lis += `<li class="page-number ${i === current ? 'active' : ''}">${i}</li>`;
                }
            } else {
                //既不大于，也不小于的情况
                // 定义两个参数,用来保存当前选中页前后要选中的数字按钮(不包括省略前后和选中的),以下是计算方法
                // buttonCount 为偶数 显示小数点 将beforeNumber向下取整就可以了
                let beforeNumber = Math.floor((current - (buttonCount - 3) / 2));
                let afterNumber = (current + (buttonCount - 3) / 2);
                // 显示左省略按钮
                if (current >= buttonCount - 1) {
                    lis += `<li class="page-number">1</li>
                        <li class="material-icons page-dot page-dot-prev"></li>`;
                };
                // 提出问题: 选中页数为1 显示了0
                // 解决 当页数为1 将beforeNumber改为1 afterNumber为除去省略号之后,前面的一个按钮
                // 同理解决current == page
                // 又有问题 点击前三个应该不分页 到 4(针对buttonCount参数来说) 了该分页 同理求得current == page
                if (current >= 1 && current < (buttonCount - 1)) {
                    beforeNumber = 1;
                    afterNumber = buttonCount - 1; // 除去省略号之后,前面的一个按钮
                } else if (current <= page && current > page - (buttonCount - 2)) {
                    //current == page  
                    beforeNumber = page - (buttonCount - 2);
                    afterNumber = page;
                }
                for (let i = beforeNumber; i <= afterNumber; i++) {
                    //6 <= 6.5 是可以的 7 <= 6.5不行
                    lis += `<li class="page-number ${i === current ? "active" : ""
                        }">${i}</li>`;
                }
                // 显示右省略按钮
                if (current <= page - (buttonCount - 2)) {
                    //控制在小于等于8的时候出现，否则就隐藏
                    lis += `
                        <li class="material-icons page-dot page-dot-next"></li>
                        <li class="page-number">${page}</li>`;
                };
            }
            // 最后拼接右按钮
            // 当前页数不是总页数就为可点击态,否则就是不可点击状态
            lis += `<li class="material-icons page-btn page-btn-next ${current !== page ? "isClick" : "notClick"}">keyboard_arrow_right</li>`;
            //把内容添加到_pagination
            _pagination.innerHTML = lis;
            // 点击数字按钮
            const _pageNumbers = document.querySelectorAll(".page-number");
            _pageNumbers.forEach((item) => {
                item.addEventListener("click", () => {
                    // item.innerHTML为字符串 需要转为数字
                    current = parseInt(item.innerHTML);
                    createPagination();
                })
            })
            // 下一页
            const _pageBtnNext = document.querySelector(".page-btn-next");
            _pageBtnNext.addEventListener("click", () => {
                if (current !== page) {
                    current++;
                    createPagination();
                }
            })
            // 上一页
            const _pageBtnPrev = document.querySelector(".page-btn-prev");
            _pageBtnPrev.addEventListener("click", () => {
                if (current !== 1) {
                    current--;
                    createPagination();
                }
            })

            // 前进 buttonCount - 2 格
            const _pageDotNext = document.querySelector(".page-dot-next");
            // 因为省略按钮会v-show 直接绑定会报找不到元素错误
            _pageDotNext?.addEventListener("click", () => {
                current += buttonCount - 2;
                createPagination();
            })
            // 后退 buttonCount - 2 格
            const _pageDotPrev = document.querySelector(".page-dot-prev");
            _pageDotPrev?.addEventListener("click", () => {
                current -= buttonCount - 2;
                createPagination();
            });
        }
        /******************创建分页列表结束**************************/
        createPagination();
    </script>
</body>

</html>